﻿using System;
using System.Runtime.InteropServices;

namespace Jeelu.API.Wrapper
{
    /// <summary>
    /// 系统时间的修改。
    /// </summary>
    public class SystemDateTime
    {
        [DllImport("Kernel32.dll")]
        private static extern Boolean SetLocalTime(ref APIDateTime st);

        [DllImport("kernel32.dll")]
        public static extern void GetLocalTime(ref APIDateTime lpSystemTime);

        /// <summary>
        /// 设置系统时间
        /// </summary>
        /// <param name="newDateTime">新时间</param>
        /// <returns></returns>
        public static bool SetLocalTime(DateTime newDateTime)
        {
            var st = new APIDateTime
                         {
                             Year = Convert.ToUInt16(newDateTime.Year),
                             Month = Convert.ToUInt16(newDateTime.Month),
                             Day = Convert.ToUInt16(newDateTime.Day),
                             DayOfWeek = Convert.ToUInt16(newDateTime.DayOfWeek),
                             Hour = Convert.ToUInt16(newDateTime.Hour),
                             Minute = Convert.ToUInt16(newDateTime.Minute),
                             Second = Convert.ToUInt16(newDateTime.Second),
                             MilliSeconds = Convert.ToUInt16(newDateTime.Millisecond)
                         };
            return SetLocalTime(ref st);
        }

        /// <summary>
        /// 系统时间的结构封装
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct APIDateTime : IEquatable<APIDateTime>
        {
            public ushort Year;
            public ushort Month;
            public ushort DayOfWeek;
            public ushort Day;
            public ushort Hour;
            public ushort Minute;
            public ushort Second;
            public ushort MilliSeconds;

            public override bool Equals(object obj)
            {
                if (ReferenceEquals(null, obj)) return false;
                if (obj.GetType() != typeof(APIDateTime)) return false;
                return Equals((APIDateTime)obj);
            }

            public bool Equals(APIDateTime other)
            {
                return other.Year == Year && other.Month == Month && other.DayOfWeek == DayOfWeek && other.Day == Day && other.Hour == Hour && other.Minute == Minute && other.Second == Second && other.MilliSeconds == MilliSeconds;
            }

            public override int GetHashCode()
            {
                unchecked
                {
                    int result = Year.GetHashCode();
                    result = (result * 397) ^ Month.GetHashCode();
                    result = (result * 397) ^ DayOfWeek.GetHashCode();
                    result = (result * 397) ^ Day.GetHashCode();
                    result = (result * 397) ^ Hour.GetHashCode();
                    result = (result * 397) ^ Minute.GetHashCode();
                    result = (result * 397) ^ Second.GetHashCode();
                    result = (result * 397) ^ MilliSeconds.GetHashCode();
                    return result;
                }
            }

            public static bool operator ==(APIDateTime left, APIDateTime right)
            {
                return left.Equals(right);
            }

            public static bool operator !=(APIDateTime left, APIDateTime right)
            {
                return !left.Equals(right);
            }

            public override string ToString()
            {
                return string.Format("{0}-{1}-{2}({3}) {4}:{5}:{6}:{7}",
                                     Year, Month, Day, DayOfWeek, Hour, Second, Minute, MilliSeconds);
            }
        }

    }
}